﻿using System;
using System.Collections.Generic;
using System.Text;

namespace TLang.Ast
{
    using Values;

    public class Subscript : Node
    {
        public Node value;
        public Node index;


        public Subscript(Node value, Node index, String file, int start, int end, int line, int col) : base(file, start, end, line, col)
        {
            this.value = value;
            this.index = index;
        }

        public override Value Interp(Scope s)
        {
            Value vector = value.Interp(s);
            Value indexValue = index.Interp(s);

            if (!(vector is Vector))
            {
                Util.Abort(value, "subscripting non-vector: " + vector);
                return null;
            }

            if (!(indexValue is IntValue))
            {
                Util.Abort(value, "subscript " + index + " is not an integer: " + indexValue);
                return null;
            }

            List<Value> values = ((Vector)vector).Values;
            int i = ((IntValue)indexValue).Value;

            if (i >= 0 && i < values.Count)
            {
                return values[i];
            }
            else
            {
                Util.Abort(this, "subscript out of bound: " + i + " v.s. [0, " + (values.Count - 1) + "]");
                return null;
            }
        }

        public override Value Typecheck(Scope s)
        {
            return null;
        }


        public void set(Value v, Scope s)
        {
            Value vector = value.Interp(s);
            Value indexValue = index.Interp(s);

            if (!(vector is Vector))
            {
                Util.Abort(value, "subscripting non-vector: " + vector);
            }

            if (!(indexValue is IntValue))
            {
                Util.Abort(value, "subscript " + index + " is not an integer: " + indexValue);
            }

            Vector vector1 = (Vector)vector;
            int i = ((IntValue)indexValue).Value;

            if (i >= 0 && i < vector1.Size())
            {
                vector1.Set(i, v);
            }
            else
            {
                Util.Abort(this, "subscript out of bound: " + i + " v.s. [0, " + (vector1.Size() - 1) + "]");
            }
        }


        public override String ToString()
        {
            return "(ref " + value + " " + index + ")";
        }
    }
}
